package com.googlecode.httpfilter.org.littleshoot.proxy;

import java.util.concurrent.Future;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;

/**
 * Default cache manager for the proxy.
 */
public class DefaultProxyCacheManager implements ProxyCacheManager {
    
    public DefaultProxyCacheManager(){} 
    public boolean returnCacheHit(HttpRequest request, Channel channel) {
        // TODO Auto-generated method stub
        return false;
    }
    
    /*
     * 

    private final CacheManager cacheManager = new CacheManager();
    
    public DefaultProxyCacheManager() {
        this.cacheManager.addCache(ProxyConstants.CACHE);
        this.cacheManager.addCache(ProxyConstants.CHUNKS_CACHE);
        this.cacheManager.addCache(ProxyConstants.CHUNK_CACHE);
    }

    public boolean returnCacheHit(final HttpRequest httpRequest, 
        final Channel channel) {
        final String uri = ProxyUtils.cacheUri(httpRequest);
        final Cache cache = this.cacheManager.getCache(ProxyConstants.CACHE);
        final Element elem = cache.get(uri);
        if (elem != null) {
            log.info("Found element in cache for URI: {}", uri);
            final CachedHttpResponse cached = 
                (CachedHttpResponse) elem.getObjectValue();
            final ChannelFutureListener cfl = cached.getChannelFutureListener();
            final ChannelFuture cf = channel.write(cached.getChannelBuffer());
            cf.addListener(cfl);
            log.info("Wrote response from cache!!");
            return true;
        }
        */
        
        
        /*
        final Cache chunkedCache = 
            this.cacheManager.getCache(ProxyConstants.CHUNKS_CACHE);
        final Element chunkedElem = chunkedCache.get(uri);
        if (chunkedElem != null) {
            log.info("Found chunk element in cache");
            final CachedHttpChunks chunker = 
                (CachedHttpChunks) chunkedElem.getObjectValue();
            if (chunker.isComplete()) {
                log.info("Writing all chunks from cache!!");
                return chunker.writeAllChunks(channel);
            }
            else {
                // TODO: Return a 206 partial response with whatever data
                // we have. 
                //
                // See: http://tools.ietf.org/html/rfc2616#section-13.8
            }
        }
        else {
            log.info("No matching element for: {}", uri);
        }
        */
    /*
        return false;
    }
    */
    
    public Future<String> cache(final HttpRequest httpRequest, 
        final HttpResponse httpResponse, final Object response, 
        final ChannelBuffer encoded) {
        
        // We can't depend on the write position and such of the
        // original buffer, so make a duplicate.
        
        // NOTE: This does not copy the actual bytes.
        /*
        final ChannelBuffer copy = encoded.duplicate();
        
        final Callable<String> task = new Callable<String>() {
            public String call() {
                final String uri = ProxyUtils.cacheUri(httpRequest);
                if (!isCacheable(httpRequest, httpResponse)) {
                    log.info("Not cachable: {}", uri);
                    return uri;
                }
                log.info("Response is cacheable -- caching {}", uri);
                
                // We store the ChannelFutureListener so we don't have to
                // keep the request and response objects in memory to 
                // determine what to do after writing the response.
                final ChannelFutureListener cfl = 
                    ProxyUtils.newWriteListener(httpRequest, httpResponse, 
                        response);
                
                if (response instanceof HttpResponse) {
                    final HttpResponse hr = (HttpResponse) response;
                    // We don't currently support caching chunked responses.
                    if (hr.isChunked()) {
                        return uri;
                    }
                    final Cache cache = 
                        cacheManager.getCache(ProxyConstants.CACHE);
                    final CachedHttpResponse cached = 
                        new DefaultCachedHttpResponse(copy, cfl);
                    log.info("Adding to response cache under URI: {}", uri);
                    cache.put(new Element(uri, cached));
                }
//                else if (response instanceof HttpChunk) {
//                    final Cache cache = 
//                        cacheManager.getCache(ProxyConstants.CHUNKS_CACHE);
//                    final CachedHttpChunks cacher;
//                    synchronized (cache) {
//                        final Element chunkedElem = cache.get(uri);
//                        if (chunkedElem != null) {
//                            cacher = 
//                                (CachedHttpChunks) chunkedElem.getObjectValue();
//                        }
//                        else {
//                            cacher = new DefaultCachedHttpChunks(
//                                cacheManager, httpRequest, cfl);
//                            cache.put(new Element(uri, cacher));
//                        }
//                    }
//                    log.info("Adding to chunk cache under URI: {}", uri);
//                    cacher.cache((HttpChunk)response, copy);
//                }
//                else {
//                    log.error("Unknown response type: {}", 
//                        response.getClass());
//                }
                return uri;
            }
        };
        log.info("Submitting task");
        return this.cacheExecutor.submit(task);
        */
        return null;
    }
    
}
